// #pragma once

// #include "../comm/util.hpp"
// #include "../comm/log.hpp"

// #include <iostream>
// #include <string>
// #include <vector>
// #include <unordered_map>
// #include <fstream>
// #include <cassert>

// namespace ns_model
// {
//     using namespace std;
//     using namespace ns_log;
//     using namespace ns_util;

//     const std::string question_list = "./questions/question.list";
//     const std::string question_path = "./questions/";

//     struct Question // 一道题目都有哪些属性
//     {
//         std::string number; // 题目编号 唯一值
//         std::string title; // 标题
//         std::string level; // 难度
//         int cpu_limit; // 时间要求(s)
//         int mem_limit; // 空间要求(kb)
//         std::string desc; // 描述
//         std::string header; // 预设代码
//         std::string tail; // 测试用例 header + tail = 完整代码
//     };

//     class Model
//     {
//     private:
//         // <题号，题目内容>
//         unordered_map<string, Question> questions;
//     public:
//         Model()
//         {
//             // 题单加载不出来，直接可以报错了
//             assert(LoadQuestionList(question_list));
//         }

//         ~Model()
//         {}

//         // 加载配置文件
//         // questions/question.list + 题目编号
//         bool LoadQuestionList(const string& question_list)
//         {
//             ifstream in(question_list);
//             if(!in.is_open()) {
//                 LOG(FATAL) << "加载题库失败! 检查题库文件是否存在" << "\n";
//                 return false;
//             }

//             string line;
//             while(getline(in, line)) // 按行读取题目信息
//             {
//                 vector<string> tokens;
//                 StringUtil::SplitString(line, &tokens, " ");\
//                 // 编号 标题 难度 时间限制 空间限制
//                 // 1 判断回文数 简单 1 30000
//                 if(tokens.size() != 5) {
//                     LOG(WARNING) << "题目信息格式错误! 检查题目信息文件" << "\n";
//                     continue;
//                 }

//                 Question q;
//                 q.number = tokens[0];
//                 q.title = tokens[1];
//                 q.level = tokens[2];
//                 q.cpu_limit = atoi(tokens[3].c_str());
//                 q.mem_limit = atoi(tokens[4].c_str());

//                 // 设置题目链接
//                 string path = question_path;
//                 path += q.number;
//                 path += "/";
//                 // ReadFile（从目标文件读取）: 目标文件、读取的内容、是否保留换行
//                 FileUtil::ReadFile(path + "desc.txt", &(q.desc), true);
//                 FileUtil::ReadFile(path + "header.cpp", &(q.header), true);
//                 FileUtil::ReadFile(path + "tail.cpp", &(q.tail), true);

//                 // questions.insert(make_pair(question.number, question));
//                 questions.insert({q.number, q});
//             }
//             LOG(INFO) << "加载题库成功" << "\n";
//             return true;
//         }


//         // 获取所有题目 | out: 输出型参数
//         bool GetAllQuestions(vector<Question> *out)
//         {
//             if(questions.size() == 0) {
//                 LOG(ERROR) << "(用户)获取题库失败" << "\n";
//                 return false;
//             }
//             // 循环获取每个题目
//             for(const auto &q : questions)
//             {
//                 out->push_back(q.second);
//             }

//             return true;
//         }


//         // 获取单个题目
//         bool GetSingleQuestion(const std::string &number, Question* out)
//         {
//             const auto& iter = questions.find(number);
//             if(iter == questions.end()) {
//                 LOG(ERROR) << "(用户)获取题目失败，题目编号: " << number << "\n";
//                 return false;
//             }

//             (*out) = iter->second;
//             return true;
//         }
//     };
// }